package com.reyco1.medusa.data
{
	import com.reyco1.medusa.debug.Debugger;
	import com.reyco1.medusa.core.IDisposable;
	
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;

	public class ObjectPool extends Object
	{
		private var _objectType:Class;
		private var objectList:Array;
		
		public function ObjectPool(classType:Class, count:int = 0)
		{
			_objectType = classType;
			objectList = [];
			if(count > 0) allocate(count);
		}
		
		public function allocate(count:int):*
		{
			var m:int = count - length;
			
			for (var i:uint = 0; i < m; i++) 
				addObject(createObject());
		}
		
		public function getObject():*
		{
			return (length > 0) ? objectList.pop() : createObject();
		}
		
		public function returnObject(object:*):void
		{
			var type:Object = getDefinitionByName(getQualifiedClassName(object));
			
			if (type != objectType) 
				Debugger.log("Returned object type does not match. Expected " + objectType + ", got " + type, "Object Pool", "error");
			
			if (object is IDisposable)
			{
				(object as IDisposable).clear();
			}
			
			addObject(object);
		}
		
		public function containsObject(object:*):Boolean
		{
			return objectList.indexOf(object) != -1;
		}
		
		public function empty():void
		{
			objectList = [];
		}
		
		/*  private */
		
		private function addObject(object:*):*
		{
			if(!containsObject(object)) objectList[objectList.length] = object;			
			return object;
		}
		
		private function createObject():*
		{
			return new objectType();
		}
		
		/* properties */

		public function get objectType():Class
		{
			return _objectType;
		}
		
		public function get length():Number
		{
			return objectList.length;
		}

	}
}